package main;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MatrixPassage {

	String termCount;

	String termFormatted;

	String topPassages;

	int clusterSize;

	int outputLine = 1000;

	String outputFile;

	List topics;

	List termsTotal;

	final static int totalSize = 1000;

	public MatrixPassage() {

		initConfig();

		read();
		System.out.println("sort begin.............");
		Date begin = new Date();

		getTotalTerms();

		for (Iterator iter = topics.iterator(); iter.hasNext();) {
			Topic topic = (Topic) iter.next();
			matrix(topic.getPassages());
		}
		System.out.println("sort end.............");
		Date end = new Date();
		write(topics);
		System.out.println("sort time:" + (end.getTime() - begin.getTime()));

	}

	private void getTotalTerms() {
		// find all terms
		termsTotal = new ArrayList();
		for (Iterator iterTopic = topics.iterator(); iterTopic.hasNext();) {
			Topic topic = (Topic) iterTopic.next();
			// termsTotal = new ArrayList();
			List psgs = topic.getPassages();
			for (Iterator iter = psgs.iterator(); iter.hasNext();) {
				Passage psg = (Passage) iter.next();
				String[] terms = psg.getFoundTerms();
				for (int i = 0; i < terms.length; i++) {
					if (!termsTotal.contains(terms[i])) {
						termsTotal.add(terms[i]);
					}
				}
			}
			matrix(topic.getPassages());
		}

	}

	private void matrix(List psgs) {

		// contruct terms
		for(Iterator iter = psgs.iterator(); iter.hasNext();) {
			Passage psg = (Passage) iter.next();
			StringBuffer outSb = new StringBuffer(psg.getTopicID()).append(",");
			for(Iterator iterTerm = termsTotal.iterator();iterTerm.hasNext();){
				String theTerm = (String) iterTerm.next();
				boolean isExist = false;
				String[] terms = psg.getFoundTerms();
				for(int i=0;i<terms.length;i++){
					if(theTerm.equals(terms[i])){
						outSb.append(theTerm).append(",");
						isExist = true;
						break;
					}
				}
				if(!isExist){
					outSb.append("n,");
				}
			}
			psg.setOutString(outSb.toString());
		}

	}

	private void write(List topics) {
		try {
			BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
			for (Iterator iter = topics.iterator(); iter.hasNext();) {
				Topic topic = (Topic) iter.next();
				int i = 0;
				for (Iterator itP = topic.getPassages().iterator(); itP.hasNext() && i < outputLine; i++) {
					Passage psg = (Passage) itP.next();
					bw.write(psg.getOutString() + "\r\n");
					System.out.println(psg);
				}

			}
			bw.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void read() {
		topics = new ArrayList();
		System.out.println("read file begin.............");
		try {

			// readTopPassages();
			readTermFormatted();

			readTermCount();

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("read file end.............");

	}

	/**
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private void readTermFormatted() throws FileNotFoundException, IOException {
		BufferedReader fmt_file = new BufferedReader(new FileReader(termFormatted));
		for (String tmp = fmt_file.readLine(); tmp != null; tmp = fmt_file.readLine()) {
			String[] tmpArr = tmp.split(" ");
			if (tmpArr.length == 7) {
				Topic topic = getTopic(tmpArr[0]);
				if (topic == null) {
					topic = new Topic();
					topic.setId(tmpArr[0]);
					topics.add(topic);
				}

				Passage psg = new Passage();
				psg.setTopicID(tmpArr[0]);
				psg.setDocumentID(tmpArr[1]);
				psg.setOutString(tmp);
				topic.addPassage(psg);
			} else {
				System.err.println("file format error!");
			}
		}
		fmt_file.close();
	}

	/**
	 * @param id
	 * @return
	 */
	private Topic getTopic(String id) {
		for (Iterator iter = topics.iterator(); iter.hasNext();) {
			Topic thetopic = (Topic) iter.next();
			if (id.equals(thetopic.getId())) {
				return thetopic;
			}
		}
		return null;
	}

	/**
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private BufferedReader readTermCount() throws FileNotFoundException, IOException {
		BufferedReader top_file = new BufferedReader(new FileReader(termCount));
		Topic topic = null;
		int i = 0;
		for (String tmp = top_file.readLine(); tmp != null; tmp = top_file.readLine()) {
			if (tmp.startsWith("Topic#")) {
				String topicid = tmp.replaceFirst("Topic#", "");
				topic = this.getTopic(topicid);
				i = 0;
			} else if (tmp.startsWith("passage")) {
				if (topic != null) {
					List psgs = topic.getPassages();

					Passage psg = (Passage) psgs.get(i);
					Pattern p = Pattern.compile("passage .* terms was found >> ");
					Matcher m = p.matcher(tmp);
					StringBuffer sb = new StringBuffer();
					if (m.find()) {
						m.appendReplacement(sb, "");
						m.appendTail(sb);
					} else {
						Pattern p2 = Pattern.compile("passage .* terms was found\\.");
						Matcher m2 = p2.matcher(tmp);
						if (m2.find()) {
							sb = new StringBuffer();
						}
					}
					psg.setTerms(sb.toString());
					psg.setFoundTerms(sb.toString().split(" "));
					i++;
				}
			}
		}
		top_file.close();
		return top_file;
	}

	/**
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private void initConfig() {
		try {
			BufferedReader conf_file = new BufferedReader(new FileReader("config/matrix_passage_config.properties"));
			for (String tmp = conf_file.readLine(); tmp != null; tmp = conf_file.readLine()) {
				String[] conf = tmp.split("=");
				if (conf[0].equals("term-count-of-txts-name")) {
					this.termCount = conf[1];
				} else if (conf[0].equals("formatted-combined-txt-name")) {
					this.termFormatted = conf[1];
				} else if (conf[0].equals("top-passages-name")) {
					this.topPassages = conf[1];
				} else if (conf[0].equals("cluster-size")) {
					this.clusterSize = new Integer(conf[1]).intValue();
				} else if (conf[0].equals("output-line")) {
					this.outputLine = new Integer(conf[1]).intValue();
				} else if (conf[0].equals("output-file-name")) {
					this.outputFile = conf[1];
				}
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		MatrixPassage cs = new MatrixPassage();

	}
}
